// com.sys.SysWaterQuality.service.impl.SysWebHookServiceImpl.java
package com.sys.SysWaterQuality.service.impl;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.sys.SysAlerts.domain.SysAlerts;
import com.sys.SysAlerts.mapper.SysAlertsMapper;
import com.sys.SysAquaticSpecies.domain.SysAquaticSpecies;
import com.sys.SysAquaticSpecies.mapper.SysAquaticSpeciesMapper;
import com.sys.SysTanks.domain.SysTanks;
import com.sys.SysTanks.mapper.SysTanksMapper;
import com.sys.SysWaterQuality.domain.SysWaterQuality;
import com.sys.SysWaterQuality.domain.SysWaterQualityData;
import com.sys.SysWaterQuality.domain.WaterQualityFact; // 新增导入
import com.sys.SysWaterQuality.mapper.SysWaterQualityMapper;
import com.sys.SysWaterQuality.service.SysWebHookService;
import com.sys.common.core.domain.AjaxResult;
import com.sys.common.utils.SecurityUtils;
import lombok.RequiredArgsConstructor;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class SysWebHookServiceImpl implements SysWebHookService {

    private final SysWaterQualityMapper sysWaterQualityMapper;
    private final SysTanksMapper sysTanksMapper;
    private final SysAquaticSpeciesMapper sysAquaticSpeciesMapper;
    private final SysAlertsMapper sysAlertsMapper;
    private final KieContainer kieContainer;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult processWaterQualityData(Map<Object, Object> body) {
        try {
            System.out.println("=== 开始处理水质数据 ===");

            // === 第一步：数据获取和处理 ===
            System.out.println("第一步：数据获取和处理");
            SysWaterQualityData data = parseWaterQualityData(body);

            // === 第二步：规则引擎对比 ===
            System.out.println("第二步：规则引擎对比");
            executeRules(data);

            // === 第三步：数据入库 ===
            System.out.println("第三步：数据入库");
            saveWaterQualityData(data);

            System.out.println("=== 水质数据处理完成 ===");
            return AjaxResult.success("数据处理成功");

        } catch (Exception e) {
            System.err.println("处理水质数据异常: " + e.getMessage());
            e.printStackTrace();
            return AjaxResult.error("处理失败: " + e.getMessage());
        }
    }

    /**
     * 解析水质数据
     */
    private SysWaterQualityData parseWaterQualityData(Map<Object, Object> body) {
        String id = (String) body.get("id");
        String clientid = (String) body.get("clientid");
        String payloadStr = (String) body.get("payload");

        System.out.println("接收到数据：" + payloadStr + " id:" + id + " clientid:" + clientid);

        JSONObject payloadJson = JSON.parseObject(payloadStr);

        // 提取 tankId
        String[] parts = clientid.split("_");
        int tankId = Integer.parseInt(parts[parts.length - 1]);

        // 获取养殖桶信息
        SysTanks sysTanks = sysTanksMapper.selectSysTanksById((long) tankId);
        if (sysTanks == null || sysTanks.getSpeciesId() == null) {
            throw new RuntimeException("养殖桶不存在或未配置物种信息, tankId: " + tankId);
        }

        // 获取物种信息
        SysAquaticSpecies species = sysAquaticSpeciesMapper.selectSysAquaticSpeciesById(sysTanks.getSpeciesId());

        return new SysWaterQualityData(
                id, clientid, tankId,
                getBigDecimal(payloadJson, "temperature"),
                getBigDecimal(payloadJson, "salinity"),
                getBigDecimal(payloadJson, "ph"),
                getBigDecimal(payloadJson, "dissolvedOxygen"),
                getBigDecimal(payloadJson, "ammonia"),
                getBigDecimal(payloadJson, "nitrite"),
                species
        );
    }

    // 安全获取 BigDecimal，避免 null
    private BigDecimal getBigDecimal(JSONObject json, String key) {
        return json.getBigDecimal(key) != null ? json.getBigDecimal(key) : null;
    }

    /**
     * 执行规则引擎（使用包装类避免类型污染）
     */
    private void executeRules(SysWaterQualityData data) {
        KieSession kieSession = kieContainer.newKieSession();
        try {
            // ✅ 只插入一个事实对象
            WaterQualityFact fact = new WaterQualityFact(
                    data.getTankId(),
                    data.getTemperature(),
                    data.getSalinity(),
                    data.getPh(),
                    data.getDissolvedOxygen(),
                    data.getAmmonia(),
                    data.getNitrite(),
                    data.getSpecies(),
                    this // 服务实例用于回调
            );
            kieSession.insert(fact);

            int firedRules = kieSession.fireAllRules();
            System.out.println("规则引擎执行完成，触发了 " + firedRules + " 条规则");

        } catch (Exception e) {
            System.err.println("规则引擎执行异常: " + e.getMessage());
            throw e;
        } finally {
            kieSession.dispose();
        }
    }

    /**
     * 保存水质数据
     */
    private void saveWaterQualityData(SysWaterQualityData data) {
        SysWaterQuality record = new SysWaterQuality();
        record.setId(data.getId());
        record.setTankId(data.getTankId());
        record.setTemperature(data.getTemperature());
        record.setSalinity(data.getSalinity());
        record.setPh(data.getPh());
        record.setDissolvedOxygen(data.getDissolvedOxygen());
        record.setAmmonia(data.getAmmonia());
        record.setNitrite(data.getNitrite());
        record.setUpdateTime(new Date());
        record.setRecordTime(new Date());
        record.setCreateTime(new Date());

        int result = sysWaterQualityMapper.insertSysWaterQuality(record);
        System.out.println("水质数据入库结果: " + result);
    }

    /**
     * 规则引擎回调方法 - 创建告警
     */
    public void createAlert(Integer tankId, String alertType, String severity,
                            String message, String currentValue, String standardRange) {
        SysAlerts alert = new SysAlerts();
        alert.setTankId(tankId);
        alert.setAlertType(alertType);
        alert.setSeverity(severity);
        alert.setMessage(message + " 当前值:" + currentValue + " 标准范围:" + standardRange);
        alert.setStatus("1");
        alert.setAlertTime(new Date());

        alert.setCreateTime(new Date());
        alert.setUpdateTime(new Date());

        sysAlertsMapper.insertSysAlerts(alert);
        System.out.println("创建告警记录: " + message);
    }
}